/*
 * Copyright © 2020 https://www.lrting.top/ All rights reserved.
 */


package com.zh.ch.bigdata.flink.sqlsubmit;

import com.google.common.base.Enums;
import org.apache.commons.cli.Options;

import java.io.IOException;
import java.util.*;

/**
 * @author: bigDataToAi
 * @date: 2022/7/8
 * @description:
 * @modifiedBy:
 * @version: 1.0
 */
public class SqlParser {

    public static Map<String, String>[] parseSqlFile(String sqlFilePath) throws Exception {
        String[] sqlCommands;
        if (sqlFilePath.startsWith("hdfs")) {
            sqlCommands = FileUtils.readFromHdfs(sqlFilePath).trim().split(";");
        }
        else {
            sqlCommands = FileUtils.read(sqlFilePath).trim().split(";");
        }

        Map<String, String>[] sqlMaps = new HashMap[100];
        int count = 0;
        for (String sql : sqlCommands) {
            sqlMaps[count] = call(sql);
            count++;
        }
        return parseExecuteStatSet(sqlMaps);
    }


    public void parseSqlString(String sql) {

    }

    public static Map<String, String> call(String sql) throws Exception {
        String fSql = sql.trim().toUpperCase();
        Map<String, String> sqlMap = new HashMap<>();
        for (EnumCommand sqlType : EnumCommand.values()) {
            if (deleteSqlComment(fSql).startsWith(sqlType.toString())) {
                sqlMap.put(sqlType.name(), sql);
            }
        }
        if (sqlMap.isEmpty()) {
            throw new Exception("不支持的SQL语句:" + sql);
        }
        return sqlMap;
    }

    public static String deleteSqlComment(String originalSql) {
        String[] sqlLines = originalSql.split("\n");
        StringBuilder targetSql = new StringBuilder();
        for (String sqlLine : sqlLines) {
            if (!sqlLine.startsWith("--")) {
                targetSql.append(sqlLine);
            }
        }
        return targetSql.toString();
    }

    public static Map<String, String>[] parseExecuteStatSet(Map<String, String>[] originalSqlMaps) {
        int count = 0;
        int beginPos = -1;
        int endPos= -1;
        StringBuilder executeStatSetString = new StringBuilder();
        Map<String, String> executeStatSetMap = new HashMap<>(1);
        for (Map<String, String> originalSqlMap : originalSqlMaps) {
            if (originalSqlMap == null) {
                break;
            }
            if (EnumCommand.EXECUTE_STATEMENT_SET.name().equals(originalSqlMap.keySet().iterator().next())) {
                beginPos = count;
            }
            else if(EnumCommand.END.name().equals(originalSqlMap.keySet().iterator().next())) {
                endPos = count;
            }
            count++;
        }

        if (beginPos > -1 && endPos > -1) {
            for (int i = beginPos; i < endPos + 1; i++) {
                executeStatSetString.append(originalSqlMaps[i].values().iterator().next());
                executeStatSetString.append(";");
            }
            executeStatSetMap.put(EnumCommand.EXECUTE_STATEMENT_SET.name(),
                    executeStatSetString.substring(0, executeStatSetString.length() - 1));

            int pos = 0;
            Map<String, String>[] newSqlMaps = new HashMap[originalSqlMaps.length];
            for (Map<String, String> sqlMap : Arrays.copyOfRange(originalSqlMaps, 0, beginPos)) {
                newSqlMaps[pos] = sqlMap;
                pos++;
            }
            newSqlMaps[pos] = executeStatSetMap;
            pos++;

            for (Map<String, String> sqlMap : Arrays.copyOfRange(originalSqlMaps, endPos + 1, originalSqlMaps.length - 1)) {
                newSqlMaps[pos] = sqlMap;
                pos++;
            }

            return newSqlMaps;
        }
        return originalSqlMaps;

    }


}
